package 算法;


/**
 * 实现一个队列
 *
 * @param <V>
 */
public class McQuery<V> {


    public static void main(String[] args) {

        McQuery<String> mcQuery = new McQuery<>(1);
        System.out.printf(mcQuery.toString());
        mcQuery.put("1");
        mcQuery.put("2");
        mcQuery.put("3");
        System.out.printf(mcQuery.toString());
        mcQuery.put("4");


        System.out.printf(mcQuery.toString());

    }


    /**
     * 默认大小3
     */
    private transient int size = 3;

    private transient int count = 0;


    /**
     * 头结点
     */
    private Entry<V> head;

    /**
     * 尾节点
     */
    private Entry<V> tail;


    public McQuery(int size) {
        this.size = size;
        head = new Entry<>(null);
        head.setNextEntry(tail);
    }

    public McQuery() {
        this(3);
    }

    /**
     * head 作为头结点，不做数据节点
     * <p>
     * head --> entry1 --> entry2 <-- tail
     **/
    public V put(V v) {
        Entry<V> last = new Entry<>(v);
        if (count >= size) {
            Entry removeEntry = head.nextEntry;
            Entry newFirstEntry = removeEntry.nextEntry;
            newFirstEntry = newFirstEntry == null ? last : newFirstEntry;
            head.setNextEntry(newFirstEntry);
            //wei
            Entry tag = tail;
            tag.setNextEntry(last);
        } else {
            if (tail == null) {
                head.nextEntry = last;
            } else {
                Entry tag = tail;
                tag.setNextEntry(last);
            }
            count++;
        }
        tail = last;
        return v;
    }

    @Override
    public String toString() {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("{");

        Entry entry = head.nextEntry;
        while (entry != null) {
            stringBuffer.append(entry.v.toString());
            entry = entry.nextEntry;
            if (entry != null) {
                stringBuffer.append(",");
            }
        }

        stringBuffer.append("}");
        return stringBuffer.toString();
    }

    class Entry<V> {

        Entry nextEntry;

        private V v;


        public Entry(V v) {
            this.v = v;
        }

        public Entry getNextEntry() {
            return nextEntry;
        }

        public void setNextEntry(Entry nextEntry) {
            this.nextEntry = nextEntry;
        }

        public V getV() {
            return v;
        }

        public void setV(V v) {
            this.v = v;
        }
    }
}
